package com.sunny.design.template.jdbc;

import com.google.common.collect.Lists;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * @author Sunny
 * @date 2020/1/9 23:11
 */
public abstract class JdbcTemplate {
    private DataSource dataSource;

    public JdbcTemplate(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public List<?> executeQuery(String sql, RowMapper<?> rowMapper, Object[] values) {
        try {
            //1、获取连接
            Connection conn = getConnection();
            //2、创建语句集
            PreparedStatement statement = createPreparedStatement(conn, sql);
            //3、执行语句集
            ResultSet rs = executeQuery(statement, values);
            //4、处理结果集
            List<?> result = handleResultSet(rs, rowMapper);
            //5、关闭连接
            close(conn, statement, rs);

            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private void close(Connection conn, PreparedStatement statement, ResultSet rs) throws SQLException {
        //数据库连接由连接池回收
        conn.close();
        statement.close();
        rs.close();
    }


    private List<?> handleResultSet(ResultSet rs, RowMapper<?> rowMapper) throws Exception {
        List<Object> list = Lists.newArrayList();
        int rowNum = 1;
        while (rs.next()) {
            list.add(rowMapper.mapRow(rs, rowNum++));
        }
        return list;
    }

    private PreparedStatement createPreparedStatement(Connection conn, String sql) throws SQLException {
        return conn.prepareStatement(sql);
    }

    private Connection getConnection() throws SQLException {
        return this.dataSource.getConnection();
    }

    protected ResultSet executeQuery(PreparedStatement statement, Object[] values) throws SQLException {
        for (int i = 0; i < values.length; i++) {
            statement.setObject(i, values[i]);
        }
        return statement.executeQuery();
    }
}
